package com.culture.bootdemo.controller.解决方案.限流;


import org.redisson.api.RRateLimiter;
import org.redisson.api.RateIntervalUnit;
import org.redisson.api.RateType;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;

import javax.annotation.Resource;

/**
 * @Author: wen
 * @DateTime: 2024/11/19 10:59
 * @Description: Redisson 令牌桶限流
 **/
public class RedissonRateLimiterDemo {

    @Autowired
    RedissonClient redissonClient;

    private final RRateLimiter rateLimiter;

    public RedissonRateLimiterDemo(RedissonClient redissonClient) {
        // 创建一个令牌桶限流器，key 为 "api:limit:user:login"（可以根据接口动态设置）
        this.rateLimiter = redissonClient.getRateLimiter("api:limit:user:login");
        // 初始化令牌桶：每秒生成 10 个令牌，
        this.rateLimiter.trySetRate(RateType.OVERALL, 10, 1, RateIntervalUnit.SECONDS);
    }

    /**
     * 尝试获取一个令牌，若获取成功则请求被允许，若获取失败则表示超出限流
     *
     * @return 是否允许访问
     */
    public boolean isAllowed() {
        // 尝试获取一个令牌，若成功获取则返回 true，否则返回 false
        return rateLimiter.tryAcquire();
    }


    private void runLimit() {
        // 创建 RedissonRateLimiterDemo
        RedissonRateLimiterDemo rateLimiterService = new RedissonRateLimiterDemo(redissonClient);

        // 模拟请求
        for (int i = 0; i < 10; i++) {
            if (rateLimiterService.isAllowed()) {
                System.out.println("Request " + i + " allowed");
            } else {
                System.out.println("Request " + i + " denied");
            }
        }
    }

}
